#pragma once
#include <string>
#include <functional>
#include <pthread.h>
#include <cassert>
#include <cstdio>
#define NUM 1024
class Thread; // 类声明
class Contex // 线程上下文类
{
public:
    Contex() :_this(nullptr) ,_args(nullptr) {}
    void* _args;
    Thread* _this;
};
class Thread
{
    // using func_t = std::function<void*(void*)>;
    // typedef std::function<void*(void*)> func_t;
    typedef void*(*func_t)(void*);

public:
    Thread(func_t func, void* args, int num)
        :_func(func)
        ,_args(args)
    {
        char buffer[NUM];
        snprintf(buffer, sizeof(buffer), "thread-%d ", num);
        // 线程启动
        Contex* ctx = new Contex();
        ctx->_args = args;
        ctx->_this = this;
        int n = pthread_create(&_tid, nullptr, start_routine, ctx);
        assert(n == 0);
    }
    ~Thread(){}
    static void* start_routine(void* args)// 因为第一个参数是this，所以用static
    {
        Contex* ctx = static_cast<Contex*>(args);
        void* ret = ctx->_this->run(ctx->_args);
        delete ctx;
        return ret;
    }
    void* run(void* args)
    {
        return _func(args);
    }
    void join()
    {
        int n = pthread_join(_tid, nullptr);
        assert(n == 0);
    }
private:
    std::string _name; // 线程的名字
    func_t _func;      // 线程的回调函数
    void *_args;       // 喂给线程的参数,不过是用Context类封装一下喂给线程
    pthread_t _tid;    // 线程ID
};